﻿namespace JelloPhysics
{
    using Microsoft.Xna.Framework;
    using System;
    using System.Runtime.InteropServices;

    public static class VectorTools
    {
        public static Vector2 calculateSpringForce(Vector2 posA, Vector2 velA, Vector2 posB, Vector2 velB, float springD, float springK, float damping)
        {
            Vector2 zero = posA - posB;
            float num = zero.Length();
            if (num > 0.0001f)
            {
                zero = (Vector2) (zero / num);
            }
            else
            {
                zero = Vector2.Zero;
            }
            num = springD - num;
            Vector2 vector2 = velA - velB;
            float num2 = Vector2.Dot(vector2, zero);
            return (Vector2) (zero * ((num * springK) - (num2 * damping)));
        }

        public static void calculateSpringForce(ref Vector2 posA, ref Vector2 velA, ref Vector2 posB, ref Vector2 velB, float springD, float springK, float damping, ref Vector2 forceOut)
        {
            float num = posA.X - posB.X;
            float num2 = posA.Y - posB.Y;
            float num3 = (float) Math.Sqrt((double) ((num * num) + (num2 * num2)));
            if (num3 > 0.0001f)
            {
                num /= num3;
                num2 /= num3;
            }
            else
            {
                forceOut.X = 0f;
                forceOut.Y = 0f;
                return;
            }
            num3 = springD - num3;
            float num4 = velA.X - velB.X;
            float num5 = velA.Y - velB.Y;
            float num6 = (num4 * num) + (num5 * num2);
            forceOut.X = num * ((num3 * springK) - (num6 * damping));
            forceOut.Y = num2 * ((num3 * springK) - (num6 * damping));
        }

        public static Vector2 getPerpendicular(Vector2 vec)
        {
            return new Vector2(-vec.Y, vec.X);
        }

        public static void getPerpendicular(ref Vector2 vIn, ref Vector2 vOut)
        {
            vOut.X = -vIn.Y;
            vOut.Y = vIn.X;
        }

        public static bool isCCW(ref Vector2 A, ref Vector2 B)
        {
            float num;
            Vector2 vOut = new Vector2();
            getPerpendicular(ref A, ref vOut);
            Vector2.Dot(ref B, ref vOut, out num);
            return (num >= 0f);
        }

        public static bool isCCW(Vector2 A, Vector2 B)
        {
            float num;
            Vector2 vector = getPerpendicular(A);
            Vector2.Dot(ref B, ref vector, out num);
            return (num >= 0f);
        }

        public static bool lineIntersect(Vector2 ptA, Vector2 ptB, Vector2 ptC, Vector2 ptD, out Vector2 hitPt)
        {
            float num;
            float num2;
            return lineIntersect(ptA, ptB, ptC, ptD, out hitPt, out num, out num2);
        }

        public static bool lineIntersect(ref Vector2 ptA, ref Vector2 ptB, ref Vector2 ptC, ref Vector2 ptD, out Vector2 hitPt)
        {
            float num;
            float num2;
            return lineIntersect(ref ptA, ref ptB, ref ptC, ref ptD, out hitPt, out num, out num2);
        }

        public static bool lineIntersect(ref Vector2 ptA, ref Vector2 ptB, ref Vector2 ptC, ref Vector2 ptD, out Vector2 hitPt, out float Ua, out float Ub)
        {
            hitPt = Vector2.Zero;
            Ua = 0f;
            Ub = 0f;
            float num = ((ptD.Y - ptC.Y) * (ptB.X - ptA.X)) - ((ptD.X - ptC.X) * (ptB.Y - ptA.Y));
            if (Math.Abs(num) >= 1E-06f)
            {
                float num2 = ((ptD.X - ptC.X) * (ptA.Y - ptC.Y)) - ((ptD.Y - ptC.Y) * (ptA.X - ptC.X));
                float num3 = ((ptB.X - ptA.X) * (ptA.Y - ptC.Y)) - ((ptB.Y - ptA.Y) * (ptA.X - ptC.X));
                Ua = num2 / num;
                Ub = num3 / num;
                if (((Ua >= 0f) && (Ua <= 1f)) && ((Ub >= 0f) && (Ub <= 1f)))
                {
                    hitPt = ptA + ((ptB - ptA) * Ua);
                    return true;
                }
            }
            return false;
        }

        public static bool lineIntersect(Vector2 ptA, Vector2 ptB, Vector2 ptC, Vector2 ptD, out Vector2 hitPt, out float Ua, out float Ub)
        {
            hitPt = Vector2.Zero;
            Ua = 0f;
            Ub = 0f;
            float num = ((ptD.Y - ptC.Y) * (ptB.X - ptA.X)) - ((ptD.X - ptC.X) * (ptB.Y - ptA.Y));
            if (Math.Abs(num) >= 1E-06f)
            {
                float num2 = ((ptD.X - ptC.X) * (ptA.Y - ptC.Y)) - ((ptD.Y - ptC.Y) * (ptA.X - ptC.X));
                float num3 = ((ptB.X - ptA.X) * (ptA.Y - ptC.Y)) - ((ptB.Y - ptA.Y) * (ptA.X - ptC.X));
                Ua = num2 / num;
                Ub = num3 / num;
                if (((Ua >= 0f) && (Ua <= 1f)) && ((Ub >= 0f) && (Ub <= 1f)))
                {
                    hitPt = ptA + ((ptB - ptA) * Ua);
                    return true;
                }
            }
            return false;
        }

        public static void makePerpendicular(ref Vector2 v)
        {
            float x = v.X;
            v.X = -v.Y;
            v.Y = x;
        }

        public static Vector2 reflectVector(ref Vector2 V, ref Vector2 N)
        {
            return (Vector2) (V - (N * (2f * Vector2.Dot(V, N))));
        }

        public static void reflectVector(ref Vector2 V, ref Vector2 N, ref Vector2 vOut)
        {
            float num;
            Vector2.Dot(ref V, ref N, out num);
            vOut = (Vector2) (V - (N * (2f * num)));
        }

        public static void rotateVector(ref Vector2 vecInOut, float angleRadians)
        {
            float x = vecInOut.X;
            float y = vecInOut.Y;
            float num3 = (float) Math.Cos((double) angleRadians);
            float num4 = (float) Math.Sin((double) angleRadians);
            vecInOut.X = (num3 * x) - (num4 * y);
            vecInOut.Y = (num3 * y) + (num4 * x);
        }

        public static Vector2 rotateVector(Vector2 vec, float angleRadians)
        {
            Vector2 vector = new Vector2();
            float num = (float) Math.Cos((double) angleRadians);
            float num2 = (float) Math.Sin((double) angleRadians);
            vector.X = (num * vec.X) - (num2 * vec.Y);
            vector.Y = (num * vec.Y) + (num2 * vec.X);
            return vector;
        }

        public static void rotateVector(ref Vector2 vecIn, float angleRadians, ref Vector2 vecOut)
        {
            float num = (float) Math.Cos((double) angleRadians);
            float num2 = (float) Math.Sin((double) angleRadians);
            vecOut.X = (num * vecIn.X) - (num2 * vecIn.Y);
            vecOut.Y = (num * vecIn.Y) + (num2 * vecIn.X);
        }

        public static Vector3 vec3FromVec2(ref Vector2 vec)
        {
            return new Vector3(vec.X, vec.Y, 0f);
        }

        public static Vector3 vec3FromVec2(Vector2 vec)
        {
            return new Vector3(vec.X, vec.Y, 0f);
        }

        public static Vector3 vec3FromVec2(ref Vector2 vec, float Z)
        {
            return new Vector3(vec.X, vec.Y, Z);
        }

        public static Vector3 vec3FromVec2(Vector2 vec, float Z)
        {
            return new Vector3(vec.X, vec.Y, Z);
        }
    }
}

